package org.springblade.modules.admin.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.springblade.core.mp.base.BaseEntity;
import org.springblade.core.mp.base.BaseServiceImpl;
import org.springblade.core.secure.utils.AuthUtil;
import org.springblade.core.tool.utils.Func;
import org.springblade.modules.admin.entity.MaintainMsg;
import org.springblade.modules.admin.entity.MaintainMsgRead;
import org.springblade.modules.admin.enums.MsgStatusEnum;
import org.springblade.modules.admin.enums.MsgTypeEnum;
import org.springblade.modules.admin.mapper.MaintainMsgMapper;
import org.springblade.modules.admin.service.MaintainMsgReadService;
import org.springblade.modules.admin.service.MaintainMsgService;
import org.springblade.modules.admin.vo.MaintainMsgVO;
import org.springblade.modules.admin.vo.MsgTypeVO;
import org.springblade.modules.system.entity.User;
import org.springblade.modules.system.service.IRoleMenuService;
import org.springblade.modules.system.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class MaintainMsgServiceImpl extends BaseServiceImpl<MaintainMsgMapper, MaintainMsg> implements MaintainMsgService {

//    @Autowired
//    private DelayedSend delayedSend;
	@Autowired
	private IUserService userService;
	@Autowired
	private IRoleMenuService roleMenuService;
	@Autowired
	private MaintainMsgReadService msgReadService;

    @Override
    public List<MsgTypeVO> listMsgType() {
        List<MsgTypeVO> msgTypeVOS = baseMapper.listMsgTye(AuthUtil.getUserId());
        msgTypeVOS.forEach(e -> {
            e.setTypeName(MsgTypeEnum.getName(e.getTypeId()));
        });
        return msgTypeVOS;
    }

    @Override
    public IPage<MaintainMsgVO> selectMsgPage(Integer typeId, Integer status,Integer bType, IPage<MaintainMsgVO> page) {
        return page.setRecords(baseMapper.selectMsgPage(typeId, status,bType,AuthUtil.getUserId(), page));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void sendMsg(MaintainMsg msg) {
		if(msg.getType().equals(MsgTypeEnum.ELEVATOR_RELEVANCE.getId())){
			msg.setTitle(MsgTypeEnum.getName(msg.getType()) + "ID " + msg.getTitle());
		}
        super.save(msg);
		List<Long> roleIds = roleMenuService.selectMsgRole(msg.getCode());
		if(ObjectUtil.isNotEmpty(roleIds)){
			List<User> users = userService.selectUserByRole(roleIds, msg.getReceiveTenantId() == null ? msg.getTenantId() : msg.getReceiveTenantId());
			if(ObjectUtil.isNotEmpty(users)){
				List<MaintainMsgRead> msgReads = new ArrayList<>();
				users.forEach(e -> {
					MaintainMsgRead msgRead = new MaintainMsgRead();
					msgRead.setMsgId(msg.getId());
					msgRead.setUserId(e.getId());
					msgRead.setTenantId(msg.getTenantId());
					msgReads.add(msgRead);
				});
				msgReadService.saveBatch(msgReads);
			}
		}
	}

	@Transactional(rollbackFor = Exception.class)
	@Override
	public void sendMsg(List<MaintainMsg> messages) {
		if (Func.isEmpty(messages)) {
			return;
		}

		for (MaintainMsg message : messages) {
			this.sendMsg(message);
		}
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void sendMsg(MaintainMsg msg, List<Long> userIds) {
		super.save(msg);
		if(ObjectUtil.isNotEmpty(userIds)){
			List<MaintainMsgRead> msgReads = new ArrayList<>();
			userIds.forEach(e -> {
				MaintainMsgRead msgRead = new MaintainMsgRead();
				msgRead.setMsgId(msg.getId());
				msgRead.setUserId(e);
				msgReads.add(msgRead);
			});
			msgReadService.saveBatch(msgReads);
//				MaintainMsgVO msgVO = baseMapper.selectMsgById(msg.getId());
//				delayedSend.sendMsg(System.currentTimeMillis(), JSONObject.toJSONString(msgVO));
		}
	}

	@Override
	public Long sendMsg(MaintainMsg msg, List<Long> userIds, String tenantId) {
		msg.setTenantId(tenantId);
		super.save(msg);
		if(ObjectUtil.isNotEmpty(userIds)){
			List<MaintainMsgRead> msgReads = new ArrayList<>();
			userIds.forEach(e -> {
				MaintainMsgRead msgRead = new MaintainMsgRead();
				msgRead.setMsgId(msg.getId());
				msgRead.setUserId(e);
				msgRead.setTenantId(tenantId);
				msgReads.add(msgRead);
			});
			msgReadService.saveBatch(msgReads);
		}
		return msg.getId();
	}

	@Override
	public Boolean readBath(List<Long> typeIds, Long userId) {
		List<Long> msgIds = super.list(Wrappers.<MaintainMsg>lambdaQuery().in(MaintainMsg::getType,typeIds)).stream().map(BaseEntity::getId).collect(Collectors.toList());
		return msgReadService.update(Wrappers.<MaintainMsgRead>lambdaUpdate().set(MaintainMsgRead::getStatus, MsgStatusEnum.UNREAD.getId()).in(MaintainMsgRead::getMsgId,msgIds).eq(MaintainMsgRead::getUserId,userId));
	}

	@Override
	public Boolean read(Long id, Long userId) {
		return msgReadService.update(Wrappers.<MaintainMsgRead>lambdaUpdate().set(MaintainMsgRead::getStatus, MsgStatusEnum.UNREAD.getId()).eq(MaintainMsgRead::getMsgId,id).eq(MaintainMsgRead::getUserId,userId));
	}
}

